package net.lulihu.pangolin.headless.client.kit;

import io.netty.channel.Channel;
import io.netty.util.AttributeKey;
import net.lulihu.pangolin.headless.client.component.ClientNetworkComponent;
import net.lulihu.pangolin.headless.common.container.BeanUtil;
import net.lulihu.pangolin.headless.common.util.ReadWriteLockKit;

/**
 * 连接代理主通道设置工具
 * <p>
 * 用来确定代理主通道唯一
 */
public class CmdChannelKit {

    private static volatile Channel cmdChannel;

    private static ReadWriteLockKit lock = new ReadWriteLockKit();

    /**
     * Cmd 通道标识
     */
    private static final AttributeKey<Boolean> CMD_CHANNEL_ID = AttributeKey.newInstance("cmd_channel_id");

    /**
     * 设置cmd主通道
     *
     * @param cmdChannel cmd主通道
     */
    public static void setCmdChannel(Channel cmdChannel) {
        lock.exeWriteLockMethod(() -> {
            if (CmdChannelKit.cmdChannel != null && CmdChannelKit.cmdChannel == cmdChannel) return;
            if (CmdChannelKit.cmdChannel != null && cmdChannel.isActive()) {
                CmdChannelKit.cmdChannel.attr(CMD_CHANNEL_ID).set(null);
                CmdChannelKit.cmdChannel.close();
            }
            CmdChannelKit.cmdChannel = cmdChannel;
            CmdChannelKit.cmdChannel.attr(CMD_CHANNEL_ID).set(true);
        });
    }

    /**
     * 是否为cmd通道  注意在多线程情况下可能会有误差
     *
     * @param cmdChannel cmd主通道
     * @return true为是 反之不是
     */
    public static boolean ifCmdChannel(Channel cmdChannel) {
        return lock.exeReadLockMethod(() -> {
            Boolean isCmd = cmdChannel.attr(CMD_CHANNEL_ID).get();
            return isCmd != null && isCmd;
        });
    }


    /**
     * 检查是否为cmd通道
     *
     * @param channel 通道
     */
    public static void checkIfCmdChannel(Channel channel) {
        if (ifCmdChannel(channel)) {
            // 主通道关闭 重新连接
            new Thread(CmdChannelKit::reacquireCmdChannel).start();
        }
    }

    /**
     * 重新设置Cmd通道
     */
    public static void reacquireCmdChannel() {
        ClientNetworkComponent networkComponent = BeanUtil.getBean(ClientNetworkComponent.class);
        networkComponent.retryConnection();
    }


}
